import Cesium from '../Ces/Cesium'
import WeDataParserBase from '../Display/WeDataParserBase'

class AWXParser extends WeDataParserBase {
  header1 = {
    Sat96: undefined,
    byteOrder: undefined,
    sizeHeader1: undefined,
    sizeHeader2: undefined,
    sizeFilled: undefined,
    sizeRecord: undefined,
    numHeader: undefined,
    numData: undefined,
    typeProduct: undefined,
    compressMode: undefined,
    fmtFlag: undefined,
    qualityFlag: undefined,
  }
  header2 = {
    satName: undefined,
    year: undefined,
    month: undefined,
    day: undefined,
    hour: undefined,
    minute: undefined,
    channel: undefined,
    projection: undefined,
    width: undefined,
    height: undefined,
    leftUpLine: undefined,
    leftUpPixel: undefined,
    sample: undefined,
    boundN: undefined,
    boundS: undefined,
    boundW: undefined,
    boundE: undefined,
    centerLat: undefined,
    centerLon: undefined,
    standard1: undefined,
    standard2: undefined,
    resolutionH: undefined,
    resolutionV: undefined,
    gridFlag: undefined,
    gridvalue: undefined,
    sizePalette: undefined,
    sizeCalibration: undefined,
    sizeNavigation: undefined,
    reserved: undefined,
  }
  view = undefined

  requestImage(url, getUrlCallback) {
    if (getUrlCallback) url = getUrlCallback(url) + ''
    return Cesium.Resource.fetchArrayBuffer(url).then(arrayBuffer => {
      return Promise.resolve(this.parse(arrayBuffer))
    })
  }

  parse(arrayBuffer) {
    const sizeOfUint16 = Uint16Array.BYTES_PER_ELEMENT
    const uint8Array = new Uint8Array(arrayBuffer)
    const view = this.view = new DataView(arrayBuffer)

    let byteOffset = 0

    this.header1.Sat96 = Cesium.getStringFromTypedArray(uint8Array, byteOffset, 12)
    byteOffset += 12
    this.header1.byteOrder = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.sizeHeader1 = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.sizeHeader2 = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.sizeFilled = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.sizeRecord = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.numHeader = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.numData = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.typeProduct = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.compressMode = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header1.fmtFlag = Cesium.getStringFromTypedArray(uint8Array, byteOffset, 8)
    byteOffset += 8
    this.header1.qualityFlag = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16

    this.header2.satName = Cesium.getStringFromTypedArray(uint8Array, byteOffset, 8)

    byteOffset += 8
    this.header2.year = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.month = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.day = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.hour = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.minute = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.channel = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.projection = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.width = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.height = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.leftUpLine = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.leftUpPixel = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.sample = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.boundN = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.boundS = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.boundW = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.boundE = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.centerLat = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.centerLon = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.standard1 = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.standard2 = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.resolutionH = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.resolutionV = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.gridFlag = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.gridvalue = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.sizePalette = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.sizeCalibration = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.sizeNavigation = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16
    this.header2.reserved = view.getInt16(byteOffset, true)
    byteOffset += sizeOfUint16

    const width = this.header2.width
    const height = this.header2.height

    const byteOffset2 = this.header1.sizeRecord * this.header1.numHeader
    const arrayBufferView = new Uint8Array(arrayBuffer, byteOffset2, width * height)

    const north = this.header2.boundN * 0.01
    const south = this.header2.boundS * 0.01
    const west = this.header2.boundW * 0.01
    const east = this.header2.boundE * 0.01
    // const channel = this.header2.channel

    return {
      source: {
        width,
        height,
        arrayBufferView,
        pixelFormat: Cesium.PixelFormat.ALPHA,
        pixelDatatype: Cesium.PixelDatatype.UNSIGNED_BYTE,
      },
      west,
      south,
      east,
      north,
    }
  }

  get name() {
    return this.header2.satName
  }
}

export default AWXParser
